package com.logistics.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.logistics.common.exception.BusinessException;
import com.logistics.dto.DispatchArrivalDTO;
import com.logistics.dto.DispatchConfirmDTO;
import com.logistics.dto.DispatchQueryDTO;
import com.logistics.entity.DispatchRecord;
import com.logistics.entity.TransportOrder;
import com.logistics.entity.Vehicle;
import com.logistics.mapper.DispatchRecordMapper;
import com.logistics.mapper.TransportOrderMapper;
import com.logistics.mapper.VehicleMapper;
import com.logistics.security.TenantContext;
import com.logistics.security.UserContext;
import com.logistics.service.DispatchRecordService;
import com.logistics.vo.DispatchVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 发车记录服务实现类
 */
@Service
@RequiredArgsConstructor
public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper, DispatchRecord> implements DispatchRecordService {
    
    private final VehicleMapper vehicleMapper;
    private final TransportOrderMapper transportOrderMapper;
    
    @Override
    public Page<DispatchVO> getDispatchPage(DispatchQueryDTO query) {
        Long tenantId = 1L; // 临时硬编码，后续通过认证获取
        
        Page<DispatchVO> page = new Page<>(query.getCurrent(), query.getSize());
        return baseMapper.selectDispatchPage(page, query, tenantId);
    }
    
    @Override
    @Transactional
    public DispatchRecord createDispatch(Long vehicleId, Long departureSiteId, String departureSiteName,
                                        Long arrivalSiteId, String arrivalSiteName, String remark) {
        Long tenantId = 1L; // 临时硬编码，后续通过认证获取
        Long userId = 1L; // 临时硬编码，后续通过认证获取
        Long siteId = 1L; // 临时硬编码，后续通过认证获取
        
        // 查询车辆信息
        Vehicle vehicle = vehicleMapper.selectById(vehicleId);
        if (vehicle == null) {
            throw new BusinessException("车辆不存在");
        }
        
        // 发车记录的司机使用车辆的车主信息（车主就是开车的司机）
        Long driverId = null;
        String driverName = vehicle.getOwnerName() != null ? vehicle.getOwnerName() : "临时司机";
        String driverPhone = vehicle.getOwnerPhone() != null ? vehicle.getOwnerPhone() : "";
        
        // 统计装载的订单数量
        Integer orderCount = transportOrderMapper.countByVehicleId(vehicleId, tenantId);
        if (orderCount == null) {
            orderCount = 0;
        }

        DispatchRecord existing = lambdaQuery()
            .eq(DispatchRecord::getTenantId, tenantId)
            .eq(DispatchRecord::getVehicleId, vehicleId)
            .eq(DispatchRecord::getDepartureSiteId, departureSiteId)
            .eq(DispatchRecord::getArrivalSiteId, arrivalSiteId)
            .eq(DispatchRecord::getDispatchStatus, "READY")
            .one();
        if (existing != null) {
            existing.setOrderCount(orderCount);
            if (remark != null) {
                existing.setRemark(remark);
            }
            updateById(existing);
            return existing;
        }

        // 创建发车记录
        DispatchRecord dispatch = new DispatchRecord();
        dispatch.setTenantId(tenantId);
        dispatch.setSiteId(departureSiteId);  // siteId与始发站ID一致
        dispatch.setDepartureSiteId(departureSiteId);
        dispatch.setDepartureSiteName(departureSiteName);
        dispatch.setArrivalSiteId(arrivalSiteId);
        dispatch.setArrivalSiteName(arrivalSiteName);
        dispatch.setVehicleId(vehicleId);
        dispatch.setVehiclePlate(vehicle.getPlateNumber());
        dispatch.setVehicleType(vehicle.getVehicleType());
        dispatch.setDriverId(driverId); // 可能为null
        dispatch.setDriverName(driverName);
        dispatch.setDriverPhone(driverPhone);
        dispatch.setDestination(arrivalSiteName);  // 保留旧字段兼容
        dispatch.setOrderCount(orderCount);
        dispatch.setScheduledDepartureTime(LocalDateTime.now());
        dispatch.setDispatchStatus("READY");
        dispatch.setRemark(remark);
        dispatch.setCreateBy(userId);
        
        save(dispatch);
        
        return dispatch;
    }
    
    @Override
    @Transactional
    public DispatchRecord createTempDispatch(String vehiclePlate, String vehicleType, 
                                            Long departureSiteId, String departureSiteName,
                                            Long arrivalSiteId, String arrivalSiteName,
                                            String driverName, String driverPhone, String remark) {
        Long tenantId = 1L; // 临时硬编码，后续通过认证获取
        Long userId = 1L; // 临时硬编码，后续通过认证获取
        Long siteId = 1L; // 临时硬编码，后续通过认证获取
        
        // 统计临时车辆的订单数量（通过车牌号匹配运单）
        Integer orderCount = transportOrderMapper.countByPlateNumber(vehiclePlate, tenantId);
        if (orderCount == null) {
            orderCount = 0;
        }

        DispatchRecord existing = lambdaQuery()
            .eq(DispatchRecord::getTenantId, tenantId)
            .eq(DispatchRecord::getVehiclePlate, vehiclePlate)
            .eq(DispatchRecord::getDepartureSiteId, departureSiteId)
            .eq(DispatchRecord::getArrivalSiteId, arrivalSiteId)
            .eq(DispatchRecord::getDispatchStatus, "READY")
            .one();
        if (existing != null) {
            existing.setOrderCount(orderCount);
            if (driverName != null) {
                existing.setDriverName(driverName);
            }
            if (driverPhone != null) {
                existing.setDriverPhone(driverPhone);
            }
            if (remark != null) {
                existing.setRemark(remark);
            }
            updateById(existing);
            return existing;
        }

        // 创建临时车辆发车记录
        DispatchRecord dispatch = new DispatchRecord();
        dispatch.setTenantId(tenantId);
        dispatch.setSiteId(departureSiteId);  // siteId与始发站ID一致
        dispatch.setDepartureSiteId(departureSiteId);
        dispatch.setDepartureSiteName(departureSiteName);
        dispatch.setArrivalSiteId(arrivalSiteId);
        dispatch.setArrivalSiteName(arrivalSiteName);
        dispatch.setVehicleId(null); // 临时车辆没有vehicle_id
        dispatch.setVehiclePlate(vehiclePlate);
        dispatch.setVehicleType(vehicleType);
        dispatch.setDriverId(null); // 临时司机没有driver_id
        dispatch.setDriverName(driverName != null ? driverName : "临时司机");
        dispatch.setDriverPhone(driverPhone != null ? driverPhone : "");
        dispatch.setDestination(arrivalSiteName);  // 保留旧字段兼容
        dispatch.setOrderCount(orderCount);
        dispatch.setScheduledDepartureTime(LocalDateTime.now());
        dispatch.setDispatchStatus("READY");
        dispatch.setRemark(remark);
        dispatch.setCreateBy(userId);
        
        save(dispatch);
        
        return dispatch;
    }
    
    @Override
    @Transactional
    public void confirmDispatch(DispatchConfirmDTO dto) {
        Long tenantId = 1L; // 临时硬编码
        Long userId = 1L; // 临时硬编码
        
        DispatchRecord dispatch = getById(dto.getDispatchId());
        if (dispatch == null) {
            throw new BusinessException("发车记录不存在");
        }
        
        if (!"READY".equals(dispatch.getDispatchStatus())) {
            throw new BusinessException("只能对待发车状态的记录进行确认发车");
        }
        
        // 更新发车记录（每次确认发车都重新记录时间）
        dispatch.setActualDepartureTime(dto.getActualDepartureTime() != null ? 
            dto.getActualDepartureTime() : LocalDateTime.now());
        dispatch.setDispatchStatus("DISPATCHED");
        dispatch.setDispatchConfirmBy(userId);
        // 清空之前的取消记录
        dispatch.setCancelReason(null);
        dispatch.setCancelTime(null);
        dispatch.setCancelBy(null);
        if (dto.getRemark() != null) {
            dispatch.setRemark(dto.getRemark());
        }
        updateById(dispatch);
        
        // 更新该车辆上所有已装车订单的状态为运输中
        Long vehicleId = dispatch.getVehicleId();
        if (vehicleId != null) {
            transportOrderMapper.updateOrderStatusByVehicle(vehicleId, tenantId, "LOADED", "IN_TRANSIT");
        }
    }
    
    @Override
    @Transactional
    public void confirmArrival(DispatchArrivalDTO dto) {
        Long tenantId = com.logistics.common.TenantContextHolder.getTenantId();
        Long userId = 1L; // 临时硬编码
        
        DispatchRecord dispatch = getById(dto.getDispatchId());
        if (dispatch == null) {
            throw new BusinessException("发车记录不存在");
        }
        
        if (!"DISPATCHED".equals(dispatch.getDispatchStatus())) {
            throw new BusinessException("当前状态不允许确认到达");
        }
        
        // 更新发车记录
        dispatch.setActualArrivalTime(dto.getActualArrivalTime() != null ? 
            dto.getActualArrivalTime() : LocalDateTime.now());
        dispatch.setDispatchStatus("ARRIVED");
        dispatch.setArrivalConfirmBy(userId);
        if (dto.getRemark() != null) {
            dispatch.setRemark(dto.getRemark());
        }
        updateById(dispatch);
        
        // 更新该车辆上所有运输中的订单状态为已到货
        Long vehicleId = dispatch.getVehicleId();
        if (vehicleId != null) {
            transportOrderMapper.updateOrderStatusByVehicle(vehicleId, tenantId, "IN_TRANSIT", "ARRIVED");
        }
    }
    
    @Override
    @Transactional
    public void deleteDispatch(Long dispatchId) {
        DispatchRecord dispatch = getById(dispatchId);
        if (dispatch == null) {
            throw new BusinessException("发车记录不存在");
        }
        
        if (!"READY".equals(dispatch.getDispatchStatus()) && !"CANCELLED".equals(dispatch.getDispatchStatus())) {
            throw new BusinessException("只能删除待发车或已取消状态的记录");
        }
        
        // 检查车辆上是否还有订单
        Long tenantId = com.logistics.common.TenantContextHolder.getTenantId();
        Integer orderCount = 0;
        
        if (dispatch.getVehicleId() != null) {
            // 正式车辆，按vehicleId统计
            orderCount = transportOrderMapper.countByVehicleId(dispatch.getVehicleId(), tenantId);
        } else if (dispatch.getVehiclePlate() != null) {
            // 临时车辆，按车牌号统计
            orderCount = transportOrderMapper.countByPlateNumber(dispatch.getVehiclePlate(), tenantId);
        }
        
        if (orderCount != null && orderCount > 0) {
            throw new BusinessException("该车辆上还有 " + orderCount + " 个订单，请先卸车后再删除发车记录");
        }
        
        // 物理删除发车记录
        removeById(dispatchId);
    }
    
    @Override
    @Transactional
    public void cancelDispatch(Long dispatchId, String cancelReason) {
        Long userId = 1L; // 临时硬编码
        
        DispatchRecord dispatch = getById(dispatchId);
        if (dispatch == null) {
            throw new BusinessException("发车记录不存在");
        }
        
        if (!"DISPATCHED".equals(dispatch.getDispatchStatus())) {
            throw new BusinessException("只能取消已发车状态的记录");
        }
        
        // 取消发车：恢复到待发车状态
        dispatch.setDispatchStatus("READY");
        dispatch.setCancelReason(cancelReason);
        dispatch.setCancelTime(LocalDateTime.now());
        dispatch.setCancelBy(userId);
        
        // 使用 update 方法强制更新 null 字段
        lambdaUpdate()
            .eq(DispatchRecord::getId, dispatchId)
            .set(DispatchRecord::getDispatchStatus, "READY")
            .set(DispatchRecord::getActualDepartureTime, null)  // 清空实际发车时间
            .set(DispatchRecord::getDispatchConfirmBy, null)     // 清空确认人
            .set(DispatchRecord::getCancelReason, cancelReason)
            .set(DispatchRecord::getCancelTime, LocalDateTime.now())
            .set(DispatchRecord::getCancelBy, userId)
            .update();
        
        // 将该车辆上所有运输中的订单状态回退为已装车
        Long vehicleId = dispatch.getVehicleId();
        if (vehicleId != null) {
            transportOrderMapper.updateOrderStatusByVehicle(vehicleId, 1L, "IN_TRANSIT", "LOADED");
        }
    }
    
    @Override
    public List<?> getVehicleOrders(Long vehicleId) {
        Long tenantId = 1L; // 临时硬编码
        return transportOrderMapper.selectByVehicleId(vehicleId, tenantId);
    }
}
